package scott.pushbox;

import java.io.IOException;
import java.io.InputStream;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

public class PushBoxGame {
	
	public static void main(String[] args) {
		PushBoxGame game = new PushBoxGame();
		game.start();
		game.print();
		System.out.println("--------- 下 -----------");
		game.down();
		game.print();
		System.out.println("--------- 上 -----------");
		game.up();
		game.print();
		System.out.println("--------- 上 -----------");
		game.up();
		game.print();
	}
	
	// 关数
	private int level = 0;
	// 原始地图
	private int[][] map0 = new int[20][20];
	// 游戏地图
	private int[][] map1 = new int[20][20];
	// 图片地图
	JLabel[][] labelMap;
	
	public void setLabelMap(JLabel[][] labelMap) {
		this.labelMap = labelMap;
	}

	public void start() {
		next();
	}
	
	public void next() {
		level++;
		// 读取地图
		String mapFilename = level + ".map";
		String mapFilepath = "scott/pushbox/res/map/" +  mapFilename;
		// 获取当前类的类加载器
		ClassLoader classLoader = PushBoxGame.class.getClassLoader();
		
		// 自动关闭流
		try(InputStream in = classLoader.getResourceAsStream(mapFilepath);){
			// 当前字符
			int i;
			// 编号
			int j=0;
			while( ( i = in.read()) > 0) {
				if( i < 48) {
					// 读到了换行和回车, 继续一下次循环
					continue;
				}
				// 写入地图
				int x = j % 20;
				int y = j / 20;
				i = i - 48;
				map0[y][x] = i;
				map1[y][x] = i;
				// 修改图片
				changeImage(x, y);
				j ++;
			}
		} catch (IOException e) {
			throw new RuntimeException("读取地图文件失败",e);
		}
	}
	
	public void print() {
		for(int y=0; y<20;y++) {
			for(int x=0; x<20;x++) {
				if(map1[y][x] == 0 ) {
					System.out.print("  ");
				} else {
					System.out.print(" " + map1[y][x]);
				}
			}
			System.out.println();
		}
	}
	
	// 地图上没有3就是通关
	public boolean finish() {
		for(int y=0; y<20;y++) {
			for(int x=0; x<20;x++) {
				if(map1[y][x] == 3 ) {
					return false;
				}
			}
		}
		return true;
	}
	
	public void up() {moveMan(0,-1);}
	
	public void down() {moveMan(0,1);}
	
	public void left() {moveMan(-1,0);}
	
	public void right() {moveMan(1,0);}
	
	public void loadMap() {}
	
	public int[][] getMap(){
		// 返回游戏地图
		return map1;
	}
	
	// 移动物体  x,y 是物体坐标,  ox,oy 是移动方法(-1,0左, 1,0右边, 0,-1上, 0,1下)
	private boolean moveItem(int x, int y, int ox, int oy) {
		// 移动的目标坐标
		int xx = x + ox;
		int yy = y + oy;
		
		// 判断目标坐标, 如果是房子或是另一个箱子则, 不能移动
		if(map1[yy][xx] == 1 || map1[yy][xx] == 3 || map1[yy][xx] == 9) {
			return false;
		}
		
		// 移动物体
		if(map1[y][x] == 3 || map1[y][x] == 9) {
			// 如果当前是箱子
			if(map1[yy][xx] == 4) {
				// 箱子压到目的地
				map1[yy][xx] = 9;
			} else {
				// 箱子从目的地移开
				map1[yy][xx] = 3;
			}
		} else {
			// 如果当前是小人
			if(ox==-1 && oy ==0) map1[yy][xx] = 6; // 左
			else if(ox==1 && oy ==0) map1[yy][xx] = 7; // 右
			else if(ox==0 && oy ==-1) map1[yy][xx] = 8; // 上
			else if(ox==0 && oy ==1) map1[yy][xx] = 5; // 下
		}
		// 修改目的地图片
		changeImage(xx, yy);
		
		// 恢复格子
		if (map0[y][x] == 4 || map0[y][x] == 9) {
			map1[y][x] = 4;
		} else {
			map1[y][x] = 2;
		}
		// 修改移动前的坐标处的图片
		changeImage(x, y);
		
		return true;
	}
	
	// 移动小人
	private boolean moveMan(int ox, int oy) {
		// 处于通关状态, 不能移动小人
		if(finish()) {
			return false;
		}
		int x=0,y=0;
		// 找到小人
		a: for(y=0; y<20;y++) {
			for(x=0; x<20;x++) {
				if(map1[y][x] >= 5 && map1[y][x]<=8) {
					// 找到了小人, 退出最外层小人
					break a;
				}
			}
		}
		
		// 计算下一个移动的目的地坐标
		int xx = x + ox;
		int yy = y + oy;
		
		// 判断前面是什么,
		if(map1[yy][xx] == 1) {
			// 如果是房子则不能移动
			return false;
		} else if (map1[yy][xx] == 3 || map1[yy][xx] == 9){
			// 如果是箱子则先移动箱子
			moveItem(xx,yy,ox,oy);
		}
		
		// 再移动小人
		moveItem(x,y,ox,oy);
		
		if(finish()) {
			JOptionPane.showMessageDialog(null, "厉害,进入下一关!");
			next();
		}
		
		return true;
		
	}
	
	// 修改 label 的图片
	private void changeImage(int x, int y) {
		if(this.labelMap == null) return;
		String path = "/scott/pushbox/res/imgs/%s.GIF";
		// 替换 %s 为当前坐标值
		path = String.format(path, map1[y][x]);
		JLabel label = labelMap[y][x];
		label.setIcon(new ImageIcon(PushboxWin.class.getResource(path)));
	}
}


















 